from django.db import models
from django.utils import timezone
from django.contrib.auth import get_user_model
import json

User = get_user_model()


class SystemMetric(models.Model):
    """
    系统指标模型
    """
    METRIC_TYPES = [
        ('cpu_usage', 'CPU使用率'),
        ('memory_usage', '内存使用率'),
        ('disk_usage', '磁盘使用率'),
        ('network_io', '网络IO'),
        ('database_connections', '数据库连接数'),
        ('api_response_time', 'API响应时间'),
        ('error_rate', '错误率'),
        ('throughput', '吞吐量'),
        ('active_users', '活跃用户数'),
        ('custom', '自定义指标'),
    ]
    
    name = models.CharField(max_length=100, verbose_name='指标名称')
    metric_type = models.CharField(max_length=30, choices=METRIC_TYPES, verbose_name='指标类型')
    description = models.TextField(blank=True, verbose_name='指标描述')
    unit = models.CharField(max_length=20, verbose_name='单位')
    
    # 阈值配置
    warning_threshold = models.FloatField(null=True, blank=True, verbose_name='警告阈值')
    critical_threshold = models.FloatField(null=True, blank=True, verbose_name='严重阈值')
    
    # 采集配置
    collection_interval = models.IntegerField(default=60, verbose_name='采集间隔(秒)')
    retention_days = models.IntegerField(default=30, verbose_name='数据保留天数')
    
    is_active = models.BooleanField(default=True, verbose_name='是否启用')
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')
    
    class Meta:
        db_table = 'system_metric'
        verbose_name = '系统指标'
        verbose_name_plural = '系统指标'
        unique_together = ['name', 'metric_type']
    
    def __str__(self):
        return f"{self.name} ({self.get_metric_type_display()})"


class MetricData(models.Model):
    """
    指标数据模型
    """
    metric = models.ForeignKey(SystemMetric, on_delete=models.CASCADE, verbose_name='系统指标')
    value = models.FloatField(verbose_name='指标值')
    timestamp = models.DateTimeField(verbose_name='时间戳')
    
    # 额外属性
    tags = models.JSONField(default=dict, verbose_name='标签', help_text='用于分组和过滤的标签')
    metadata = models.JSONField(default=dict, verbose_name='元数据')
    
    class Meta:
        db_table = 'metric_data'
        verbose_name = '指标数据'
        verbose_name_plural = '指标数据'
        ordering = ['-timestamp']
        indexes = [
            models.Index(fields=['metric', 'timestamp']),
            models.Index(fields=['timestamp']),
        ]
    
    def __str__(self):
        return f"{self.metric.name}: {self.value} at {self.timestamp}"
    
    def is_warning(self):
        """
        是否达到警告阈值
        """
        if self.metric.warning_threshold is not None:
            return self.value >= self.metric.warning_threshold
        return False
    
    def is_critical(self):
        """
        是否达到严重阈值
        """
        if self.metric.critical_threshold is not None:
            return self.value >= self.metric.critical_threshold
        return False


class SystemAlert(models.Model):
    """
    系统告警模型
    """
    ALERT_LEVELS = [
        ('info', '信息'),
        ('warning', '警告'),
        ('error', '错误'),
        ('critical', '严重'),
    ]
    
    STATUS_CHOICES = [
        ('active', '活跃'),
        ('acknowledged', '已确认'),
        ('resolved', '已解决'),
        ('suppressed', '已抑制'),
    ]
    
    metric = models.ForeignKey(SystemMetric, on_delete=models.CASCADE, verbose_name='相关指标')
    alert_level = models.CharField(max_length=10, choices=ALERT_LEVELS, verbose_name='告警级别')
    title = models.CharField(max_length=200, verbose_name='告警标题')
    message = models.TextField(verbose_name='告警消息')
    
    # 触发条件
    trigger_value = models.FloatField(verbose_name='触发值')
    threshold_value = models.FloatField(verbose_name='阈值')
    
    # 状态管理
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='active', verbose_name='状态')
    
    # 时间信息
    triggered_at = models.DateTimeField(auto_now_add=True, verbose_name='触发时间')
    acknowledged_at = models.DateTimeField(null=True, blank=True, verbose_name='确认时间')
    resolved_at = models.DateTimeField(null=True, blank=True, verbose_name='解决时间')
    
    # 处理人员
    acknowledged_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, related_name='acknowledged_alerts', verbose_name='确认人')
    resolved_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, related_name='resolved_alerts', verbose_name='解决人')
    
    # 额外信息
    tags = models.JSONField(default=dict, verbose_name='标签')
    metadata = models.JSONField(default=dict, verbose_name='元数据')
    
    class Meta:
        db_table = 'system_alert'
        verbose_name = '系统告警'
        verbose_name_plural = '系统告警'
        ordering = ['-triggered_at']
        indexes = [
            models.Index(fields=['status', 'alert_level']),
            models.Index(fields=['metric', 'triggered_at']),
        ]
    
    def __str__(self):
        return f"{self.title} - {self.get_alert_level_display()}"
    
    def acknowledge(self, user):
        """
        确认告警
        """
        self.status = 'acknowledged'
        self.acknowledged_at = timezone.now()
        self.acknowledged_by = user
        self.save(update_fields=['status', 'acknowledged_at', 'acknowledged_by'])
    
    def resolve(self, user):
        """
        解决告警
        """
        self.status = 'resolved'
        self.resolved_at = timezone.now()
        self.resolved_by = user
        self.save(update_fields=['status', 'resolved_at', 'resolved_by'])
    
    def suppress(self):
        """
        抑制告警
        """
        self.status = 'suppressed'
        self.save(update_fields=['status'])
    
    @property
    def duration(self):
        """
        告警持续时间
        """
        end_time = self.resolved_at or timezone.now()
        return end_time - self.triggered_at


class HealthCheck(models.Model):
    """
    健康检查模型
    """
    CHECK_TYPES = [
        ('http', 'HTTP检查'),
        ('database', '数据库检查'),
        ('redis', 'Redis检查'),
        ('service', '服务检查'),
        ('custom', '自定义检查'),
    ]
    
    STATUS_CHOICES = [
        ('healthy', '健康'),
        ('warning', '警告'),
        ('unhealthy', '不健康'),
        ('unknown', '未知'),
    ]
    
    name = models.CharField(max_length=100, verbose_name='检查名称')
    check_type = models.CharField(max_length=20, choices=CHECK_TYPES, verbose_name='检查类型')
    description = models.TextField(blank=True, verbose_name='检查描述')
    
    # 检查配置
    endpoint = models.CharField(max_length=500, blank=True, verbose_name='检查端点')
    timeout = models.IntegerField(default=30, verbose_name='超时时间(秒)')
    interval = models.IntegerField(default=60, verbose_name='检查间隔(秒)')
    
    # 状态信息
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='unknown', verbose_name='状态')
    last_check_time = models.DateTimeField(null=True, blank=True, verbose_name='上次检查时间')
    last_success_time = models.DateTimeField(null=True, blank=True, verbose_name='上次成功时间')
    
    # 统计信息
    success_count = models.IntegerField(default=0, verbose_name='成功次数')
    failure_count = models.IntegerField(default=0, verbose_name='失败次数')
    
    # 错误信息
    last_error = models.TextField(blank=True, verbose_name='最后错误')
    
    is_active = models.BooleanField(default=True, verbose_name='是否启用')
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')
    
    class Meta:
        db_table = 'health_check'
        verbose_name = '健康检查'
        verbose_name_plural = '健康检查'
        unique_together = ['name', 'check_type']
    
    def __str__(self):
        return f"{self.name} - {self.get_status_display()}"
    
    def record_success(self):
        """
        记录成功检查
        """
        self.status = 'healthy'
        self.last_check_time = timezone.now()
        self.last_success_time = timezone.now()
        self.success_count += 1
        self.last_error = ''
        self.save()
    
    def record_failure(self, error_message):
        """
        记录失败检查
        """
        self.status = 'unhealthy'
        self.last_check_time = timezone.now()
        self.failure_count += 1
        self.last_error = error_message
        self.save()
    
    @property
    def uptime_percentage(self):
        """
        可用性百分比
        """
        total_checks = self.success_count + self.failure_count
        if total_checks == 0:
            return 0
        return (self.success_count / total_checks) * 100


class PerformanceLog(models.Model):
    """
    性能日志模型
    """
    LOG_TYPES = [
        ('api_request', 'API请求'),
        ('database_query', '数据库查询'),
        ('cache_operation', '缓存操作'),
        ('file_operation', '文件操作'),
        ('external_service', '外部服务调用'),
    ]
    
    log_type = models.CharField(max_length=30, choices=LOG_TYPES, verbose_name='日志类型')
    operation = models.CharField(max_length=200, verbose_name='操作名称')
    
    # 性能指标
    duration_ms = models.FloatField(verbose_name='执行时间(毫秒)')
    memory_usage_mb = models.FloatField(null=True, blank=True, verbose_name='内存使用(MB)')
    cpu_usage_percent = models.FloatField(null=True, blank=True, verbose_name='CPU使用率(%)')
    
    # 请求信息
    user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, verbose_name='用户')
    ip_address = models.GenericIPAddressField(null=True, blank=True, verbose_name='IP地址')
    user_agent = models.TextField(blank=True, verbose_name='用户代理')
    
    # 额外数据
    request_data = models.JSONField(default=dict, verbose_name='请求数据')
    response_data = models.JSONField(default=dict, verbose_name='响应数据')
    
    # 状态信息
    success = models.BooleanField(default=True, verbose_name='是否成功')
    error_message = models.TextField(blank=True, verbose_name='错误信息')
    
    timestamp = models.DateTimeField(auto_now_add=True, verbose_name='时间戳')
    
    class Meta:
        db_table = 'performance_log'
        verbose_name = '性能日志'
        verbose_name_plural = '性能日志'
        ordering = ['-timestamp']
        indexes = [
            models.Index(fields=['log_type', 'timestamp']),
            models.Index(fields=['operation', 'timestamp']),
            models.Index(fields=['user', 'timestamp']),
        ]
    
    def __str__(self):
        return f"{self.operation} - {self.duration_ms}ms"


class SystemConfiguration(models.Model):
    """
    系统配置模型
    """
    CONFIG_TYPES = [
        ('monitoring', '监控配置'),
        ('alerting', '告警配置'),
        ('performance', '性能配置'),
        ('security', '安全配置'),
        ('integration', '集成配置'),
    ]
    
    name = models.CharField(max_length=100, verbose_name='配置名称')
    config_type = models.CharField(max_length=20, choices=CONFIG_TYPES, verbose_name='配置类型')
    description = models.TextField(blank=True, verbose_name='配置描述')
    
    # 配置值
    config_value = models.JSONField(verbose_name='配置值')
    default_value = models.JSONField(null=True, blank=True, verbose_name='默认值')
    
    # 验证规则
    validation_rules = models.JSONField(default=dict, verbose_name='验证规则')
    
    # 状态信息
    is_active = models.BooleanField(default=True, verbose_name='是否启用')
    is_sensitive = models.BooleanField(default=False, verbose_name='是否敏感')
    
    # 变更记录
    last_modified_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, verbose_name='最后修改人')
    
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')
    
    class Meta:
        db_table = 'system_configuration'
        verbose_name = '系统配置'
        verbose_name_plural = '系统配置'
        unique_together = ['name', 'config_type']
    
    def __str__(self):
        return f"{self.name} ({self.get_config_type_display()})"
    
    def get_masked_value(self):
        """
        获取脱敏后的配置值
        """
        if self.is_sensitive:
            return "***MASKED***"
        return self.config_value


class MonitoringDashboard(models.Model):
    """
    监控仪表板模型
    """
    name = models.CharField(max_length=100, verbose_name='仪表板名称')
    description = models.TextField(blank=True, verbose_name='仪表板描述')
    
    # 仪表板配置
    layout = models.JSONField(default=dict, verbose_name='布局配置')
    widgets = models.JSONField(default=list, verbose_name='组件配置')
    
    # 权限配置
    is_public = models.BooleanField(default=False, verbose_name='是否公开')
    allowed_users = models.ManyToManyField(User, blank=True, verbose_name='允许访问的用户')
    
    # 刷新配置
    auto_refresh = models.BooleanField(default=True, verbose_name='自动刷新')
    refresh_interval = models.IntegerField(default=30, verbose_name='刷新间隔(秒)')
    
    created_by = models.ForeignKey(User, on_delete=models.CASCADE, related_name='created_dashboards', verbose_name='创建者')
    is_active = models.BooleanField(default=True, verbose_name='是否启用')
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')
    
    class Meta:
        db_table = 'monitoring_dashboard'
        verbose_name = '监控仪表板'
        verbose_name_plural = '监控仪表板'
        ordering = ['-created_at']
    
    def __str__(self):
        return self.name
    
    def can_access(self, user):
        """
        检查用户是否可以访问
        """
        if self.is_public or self.created_by == user:
            return True
        return self.allowed_users.filter(id=user.id).exists()